package main

import (
	"context"
	"encoding/json"
	"log"

	"go.uber.org/zap"
	"missevanbot/config"
	"missevanbot/core"
	"missevanbot/models"
	"missevanbot/modules"
	"missevanbot/utils/logger"
)

var (
	ctx = context.Background()
)

func main() {
	config.LoadConfig()
	cfg := config.Config()

	// Initialize the Redis client.
	config.InitRDBClient(cfg.Redis)
	// Initialize the logger.
	if err := logger.Init(cfg.Log, cfg.Level); err != nil {
		log.Println("init logger failed: ", err)
		return
	}

	defer func() {
		modules.Push(modules.TitleCrash, "program exited")
		zap.S().Fatal("program exited")
	}()

	modules.Init()

	rooms := modules.RoomConfigs()
	for _, rc := range rooms {
		startBot(rc)
	}

	ch, err := modules.Subscribe()
	if err != nil {
		zap.S().Error("subscribe config failed: ", err)
		return
	}
	for msg := range ch {
		rc := models.RoomConfig{}
		if err := json.Unmarshal([]byte(msg.Payload), &rc); err != nil {
			zap.S().Error("configuration unmarshal failed: ", err)
			continue
		}
		if modules.RoomStatus(rc.ID) == modules.StatusNon {
			modules.SetRoomConfig(rc)
			startBot(rc)
		}
	}
}

// startBot creates a new bot instance via a live room configuration.
func startBot(rc models.RoomConfig) {
	if !rc.Enable {
		return
	}
	room := models.NewRoom(rc)
	err := modules.InitBot(room)
	if err != nil {
		zap.S().Errorf("init bot %s failed: %s\n", rc.Alias, err)
		return
	}
	modules.InitRoomInfo(room.ID, room.Alias, room.BotNic)
	modules.InitMode(room.ID)

	input := make(chan models.FmTextMessage, 8)
	output := make(chan string, 8)

	ctx, cancel := context.WithCancel(ctx)

	go core.Connect(ctx, cancel, input, room, core.MaxRetry)
	go core.Match(ctx, input, output, room)
	go core.Send(ctx, output, room)
	go core.Cron(ctx, output, room)
}
